// XMLMgr.cpp: implementation of the CXMLMgr class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XMLMgr.h"
#include <string>
#include <assert.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
HRESULT wi_BSTRToChar(BSTR pSrc , std::string& strBuffer)
{
	if(!pSrc) 
	{
		return E_FAIL;
	}

	DWORD cb , cwch = ::SysStringLen(pSrc);//convert even embeded NULL

	char *szOut = NULL;

	cb = ::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, NULL, 0, 0, 0);
	
	if(cb)
	{
		szOut = new char[cb];
		
		if(szOut)
		{
			szOut[cb - 1] = '\0';

			if(!::WideCharToMultiByte(CP_ACP, 0, pSrc, cwch + 1, szOut, cb, 0, 0))
			{
				delete [] szOut; //clean up if failed;
				return E_FAIL;
			}
		}

		strBuffer = szOut;
		delete szOut;
	}

	return S_OK;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
//------------------------//
// Convert char * To BSTR //
//------------------------//
HRESULT wi_CStringToBSTR(CString str, BSTR &_bstr)
{
	_bstr=str.AllocSysString(); 
	return S_OK;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

CXMLMgr* CXMLMgr::m_pThis = NULL;
/*$ ******************************************************************************
					Method Name			CXMLMgr() - Constructor	
					Parameters			None
					Return				None
					Description			It will initlize COM, set the default memory handler
********************************************************************************** */

CXMLMgr::CXMLMgr() : m_pXMLDomDoc(NULL) , m_pXMLRoot(NULL) , m_pLastItemAdded(NULL)
{
	// Initialize COM
	::CoInitialize(NULL);

	m_pThis = this;
}

/*$ ******************************************************************************
					Method Name			CXMLMgr() - Constructor	
					Parameters			None
					Return				None
					Description			Destory & Release resources
********************************************************************************** */
CXMLMgr::~CXMLMgr()
{
	Destroy();
}

/*$ ******************************************************************************
					Method Name			Initlize
					Parameters			None

					Return				HERSULT
											S_OK (on success)
											E_FAIL (on error)

					Description			It will initlize Document pointer
********************************************************************************** */
HRESULT CXMLMgr::Initlize() const
{
	HRESULT hr = CoCreateInstance(	__uuidof(MSXML::DOMDocument), 
									NULL, 
									CLSCTX_INPROC_SERVER, 
									__uuidof(MSXML::IXMLDOMDocument), 
									(void**)&m_pXMLDomDoc);

	if (FAILED(hr) )
		return hr;

	hr = m_pXMLDomDoc->put_async(VARIANT_FALSE);
	if (FAILED(hr) )
		return hr;

	hr = m_pXMLDomDoc->put_validateOnParse(VARIANT_FALSE);
	if (FAILED(hr) )
		return hr;

	// if hr is still S_OK, the operation is successful
	return m_pXMLDomDoc->put_resolveExternals(VARIANT_FALSE);
}

/*$ ******************************************************************************
					Method Name			Load	
					
					Parameters			[in] LPCSTR 
											Name & path of the .xml file to load
					Return				bool
											true (on success)
											false (on error)

					Description			It will loads a valid xml document
********************************************************************************** */
bool CXMLMgr::Load(CString lpcstrXMLFileName)
{
	//assert (lpcstrXMLFileName != NULL);

	BSTR			bstr;
	VARIANT			var;
	VARIANT_BOOL	bstatus;
	bool			bRetVal = false;
		
	wi_CStringToBSTR(lpcstrXMLFileName , bstr);

	VariantInit(&var);
	V_BSTR(&var) = SysAllocString(bstr);
	V_VT(&var) = VT_BSTR;

	// Loading xml DOM
	HRESULT hr = m_pXMLDomDoc->load(var, &bstatus);

	// If the file is loaded successfully
	if (bstatus == VARIANT_TRUE) 
	{
		// now that the document is loaded, initialize the root pointer
		m_pXMLDomDoc->get_documentElement(&m_pXMLRoot);
		bRetVal = true;
	}

	SysFreeString(bstr);

	return bRetVal;
}

/*$ ******************************************************************************
					Method Name			Save	

					Parameters			[in] LPCSTR 
											Name & path with which the .xml file is required to be stored

					Return				HRESULT
											S_OK (on success)
											E_FAIL (on error)

					Description			Save the document to the external .xml file
********************************************************************************** */
HRESULT CXMLMgr::Save(CString lpcstrXMLFileName)
{
	HRESULT hr = E_FAIL;

//	assert (lpcstrXMLFileName != NULL);
	_variant_t varString(lpcstrXMLFileName);
	//varString.bstrVal=lpcstrXMLFileName;
	hr = m_pXMLDomDoc->save(varString );

	return  hr;
}

/*$ ******************************************************************************
					Method Name			Release		
					Parameters			None
					Return				None
					Description			Release the resources
********************************************************************************** */
void CXMLMgr::Release()
{
	Release(m_pXMLDomDoc);
	Release(m_pXMLRoot);
	Release(m_pLastItemAdded);
}

/*$ ******************************************************************************
					Method Name			Release	

					Parameters			[in] MSXML2::IXMLDOMDocument*
											Doucument pointer

					Return				None
					Description			Release document pointer
********************************************************************************** */
void CXMLMgr::Release(MSXML::IXMLDOMDocument* pXMLDoc)
{
	if (pXMLDoc)
	{
		pXMLDoc->Release();
		pXMLDoc = NULL;
	}
}

/*$ ******************************************************************************
					Method Name			Release		

					Parameters			[in] MSXML2::IXMLDOMElement*
											Element to release

					Return				None
					Description			Release element pointer
********************************************************************************** */
void CXMLMgr::Release(MSXML::IXMLDOMElement* pXMLElement)
{
	if (pXMLElement)
	{
		pXMLElement->Release();
		pXMLElement = NULL;
	}
}

/*$ ******************************************************************************
					Method Name			GetText	

					Parameters			[in] MSXML2::IXMLDOMNode*
											Element which text is required

					Return				LPCSTR
											Text of the XML Element

					Description			Get the text of the node
********************************************************************************** */
CString CXMLMgr::GetText(MSXML::IXMLDOMNode* pElement)
{
	assert (pElement != NULL);

	BSTR bstr;
	pElement->get_text(&bstr);

	return ReturnBuffer(bstr);
}

/*$ ******************************************************************************
					Method Name			GetNodeName	

					Parameters			[in] MSXML2::IXMLDOMNode*
											Node, which name is required

					Return				LPCSTR
											Name of the ndoe

					Description			Get the name of the node
********************************************************************************** */
CString CXMLMgr::GetNodeName(MSXML::IXMLDOMNode* pNode)
{
	assert (pNode != NULL);

	BSTR bstr;
	pNode->get_nodeName(&bstr);

	return ReturnBuffer(bstr);
}

/*$ ******************************************************************************
					Method Name			ReturnBuffer		

					Parameters			[in] BSTR 
											BSTR string, which is required to be in LPCSTR

					Return				LPCSTR
											Output of BSTR

					Description			Convert BSTR string to LPCSTR and return it
********************************************************************************** */
CString CXMLMgr::ReturnBuffer(BSTR bstr)
{
#if 0
	std::string strTemp;
	wi_BSTRToChar(bstr , strTemp);
	
	strcpy( m_Buffer , strTemp.c_str());
	return m_Buffer;

#else
	//m_Buffer.Format(_T("%s"), char(*)bstr);
	m_Buffer=(CString )bstr;
	//CString str=(CString)bstr;
	//memcpy(&m_Buffer, &str, sizeof(str);
	return m_Buffer;
#endif
}

/*$ ******************************************************************************
					Method Name			GetFirstChild		

					Parameters			[in] MSXML2::IXMLDOMNode* 
											Node, which first child is required

					Return				MSXML2::IXMLDOMNode*
											First child of the node

					Description			Get the first element of the node
********************************************************************************** */
MSXML::IXMLDOMNode* CXMLMgr::GetFirstChild(MSXML::IXMLDOMNode* pNode) const
{
	assert (pNode != NULL);

	MSXML::IXMLDOMNode* pElem = NULL;
	pNode->get_firstChild(&pElem);

	return pElem;
}

/*$ ******************************************************************************
					Method Name			GetFirstChild	

					Parameters			None
					Return				MSXML2::IXMLDOMNode*
											First child of the root element

					Desccription		Get the first element of the root node
********************************************************************************** */
MSXML::IXMLDOMNode* CXMLMgr::GetFirstChild() const
{
	assert(m_pXMLRoot != NULL);

	MSXML::IXMLDOMNode* pChild = NULL;
	m_pXMLRoot->get_firstChild(&pChild);

	return pChild;
}

/*$ ******************************************************************************
					Method Name			GetLastChild	

					Parameters			[in] MSXML2::IXMLDOMNode*
											Node, which last element is required

					Return				MSXML2::IXMLDOMNode*
											Last element of the node

					Desccription		Get the last element of the node
********************************************************************************** */
MSXML::IXMLDOMNode * CXMLMgr::GetLastChild(MSXML::IXMLDOMNode * pNode) const
{
	assert(pNode != NULL);

	MSXML::IXMLDOMNode* pChild = NULL;
	pNode->get_lastChild(&pChild);

	return pChild;
}

/*$ ******************************************************************************
					Method Name			GetLastChild	

					Parameters			None
					Return				MSXML2::IXMLDOMNode*
											Last child of the root

					Description			Get the last element of the root node
********************************************************************************** */
MSXML::IXMLDOMNode * CXMLMgr::GetLastChild() const
{
	assert(m_pXMLRoot != NULL);

	MSXML::IXMLDOMNode* pChild = NULL;
	m_pXMLRoot->get_lastChild(&pChild);

	return pChild;
}

/*$ ******************************************************************************
					Method Name			GetNextSibling	

					Parameters			[in] MSXML2::IXMLDOMNode*
											Node which sibling is required

					Return				MSXML2::IXMLDOMNode*
											Sibling node pointer
											
					Description			Get the next sibling of the node
********************************************************************************** */
MSXML::IXMLDOMNode * CXMLMgr::GetNextSibling(MSXML::IXMLDOMNode* pNode) const
{
	assert(pNode != NULL);

	MSXML::IXMLDOMNode* pSibling = NULL;
	pNode->get_nextSibling(&pSibling);

	return pSibling;
}

/*$ ******************************************************************************
					Method Name			GetChildList	

					Parameters			[in] MSXML2::IXMLDOMNode*
											Node, which child list is required

					Return				MSXML2::IXMLDOMNodeList*
											Child list

					Description			Get the list of the child nodes contained by the node
********************************************************************************** */
MSXML::IXMLDOMNodeList	* CXMLMgr::GetChildList(MSXML::IXMLDOMNode* pNode) const
{
	assert (pNode != NULL);

	MSXML::IXMLDOMNodeList	* pXMLNodeList;
	pNode->get_childNodes(&pXMLNodeList);

	return pXMLNodeList;
}

/*$ ******************************************************************************
					Method Name			GetNoOfChilds	

					Parameters			[in] MSXML2::IXMLDOMNodeList*
											Child node list pointer
					
					 Return				long
											No. of childs

					Description			Return the no. of childrens of the node list
********************************************************************************** */
const long CXMLMgr::GetNoOfChilds(MSXML::IXMLDOMNodeList* pList) const
{
	assert (pList != NULL);

	long lLength;
	pList->get_length(&lLength);

	return lLength;
}

/*$ ******************************************************************************
					Method Name			GetItemNode	

					Parameters			[in] const long lIndex
											Index of the node in the list

										[in] MSXML2::IXMLDOMNodeList*
											Pointer of the node list

					Return				MSXML2::IXMLDOMNode*
											Node item in the list

					Description			Return node, which index and child list is provided 
********************************************************************************** */
MSXML::IXMLDOMNode	* CXMLMgr::GetItemNode(const long lIndex , MSXML::IXMLDOMNodeList* pList) const
{
	assert(pList != NULL);
	assert(lIndex >= 0);
	assert(lIndex <= GetNoOfChilds(pList));

	MSXML::IXMLDOMNode	*pNode;
	pList->get_item(lIndex , &pNode);

	return pNode;
}

/*$ ******************************************************************************
					Method Name			GetItemText

					Parameters			MSXML2::IXMLDOMNode*
											Node, which text is required

					Return				LPCSTR
											Text of the node

					Description			Get the text of the node
********************************************************************************** */
CString CXMLMgr::GetItemText(MSXML::IXMLDOMNode* pNode)
{
	assert (pNode != NULL);

	BSTR bstr;
	pNode->get_text(&bstr);
	
	return ReturnBuffer(bstr);
}

/*$ ******************************************************************************
					Method Name			CreateRoot	

					Parameters			[in] LPCSTR lpcstrRootName
											Name with which root element is required to be created

										[in] LPCSTR lpcstrRootText
											Text of the root element (can be NULL)

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Description			Create Root element with root text. Note, if there is no text required for the
										root element, then it can set to NULL.
********************************************************************************** */
HRESULT CXMLMgr::CreateRoot(CString lpcstrRootName , CString lpcstrRootText)
{
//	assert (lpcstrRootName != NULL);

	HRESULT hr = E_FAIL;

	m_pXMLRoot = CreateNode(lpcstrRootName , m_pXMLRoot);

	if (m_pXMLRoot)
	{
		if (lpcstrRootText)
			SetNodeText(lpcstrRootText , m_pXMLRoot);
		
		hr = AppendChildToParent(m_pXMLRoot , m_pXMLDomDoc);
	}

	return hr;	
}

/*$ ******************************************************************************
					Method Name			AppendChildToParent	

					Parameters			[in] MSXML2::IXMLDOMNode* pChild
											Child node to append

										[in] MSXML2::IXMLDOMNode* pParent
											Parent node, to which child will be appended

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Desccription		Append one node to another
********************************************************************************** */
HRESULT CXMLMgr::AppendChildToParent(MSXML::IXMLDOMNode *pChild, MSXML::IXMLDOMNode *pParent)
{
	assert (pChild != NULL);
	assert (pParent != NULL);

	HRESULT hr = E_FAIL;
	MSXML::IXMLDOMNode *pNode = NULL;

    hr = pParent->appendChild(pChild, &pNode);

    if (pNode) 
	{
		pNode->Release();
		pNode=NULL;
	}

	return hr;
}

/*$ ******************************************************************************
					Method Name			InsertChild	

					Parameters			[in] MSXML2::IXMLDOMNode *pNewNode
											New node to insert

										[in] MSXML2::IXMLDOMNode *pRefNode
											The address of the reference node; the newChild parameter is inserted to 
											the left of the refChild parameter. 
											
											If Null, the newChild parameter is inserted at the end of the child list.

										[in] MSXML2::IXMLDOMNode *pParentNode
											Parent node, to which new child is required to be added

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Desccription		Insert new child 
********************************************************************************** */
HRESULT CXMLMgr::InsertChild(MSXML::IXMLDOMNode *pNewNode , MSXML::IXMLDOMNode *pRefNode , MSXML::IXMLDOMNode *pParentNode)
{
	assert (pNewNode != NULL);

	HRESULT hr = E_FAIL;
	MSXML::IXMLDOMNode *pOutNode = NULL;

	_variant_t varNodeRef;

	if (NULL != pRefNode)
		varNodeRef = pRefNode;

	if (!pParentNode)
		pParentNode = m_pXMLRoot;
	
	hr = pParentNode->insertBefore(pNewNode , varNodeRef , &pOutNode);

	return hr;

}

/*$ ******************************************************************************
					Method Name			CreateXMLFileHeader	

					Parameters			None

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)
											
					Desccription		Create XML Header
********************************************************************************** */
HRESULT CXMLMgr::CreateXMLFileHeader()
{
	HRESULT hr = E_FAIL;
	MSXML::IXMLDOMProcessingInstruction *pi = NULL;
	BSTR bstr1 = SysAllocString(L"xml");
	BSTR bstr2 = SysAllocString(L"version='1.0'");

	// Creating the processing instruction, that will create the xml tag
	hr = m_pXMLDomDoc->createProcessingInstruction(bstr1 ,bstr2, &pi);

	if (S_OK == hr)
		AppendChildToParent(pi , m_pXMLDomDoc);	// Putting the header tag into the DOM

	pi->Release();

	SysFreeString(bstr1);
	SysFreeString(bstr2);

	return hr;
}

/*$ ******************************************************************************
					Method Name			CreateComments	

					Parameters			[in] LPCSTR
											Comments

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Desccription		Write particular comments to document
********************************************************************************** */
HRESULT CXMLMgr::CreateComments(CString lpcstrComment)
{
//	assert (lpcstrComment != NULL);
	HRESULT hr = E_FAIL;

	// Comment Interface
	MSXML::IXMLDOMComment	*pComment = NULL;

	// Comment itself
	BSTR bstr;
	wi_CStringToBSTR(lpcstrComment , bstr);
	
	// Creating the comment
	hr = m_pXMLDomDoc->createComment(bstr, &pComment);

	if (S_OK == hr)
		hr = AppendChildToParent(pComment, m_pXMLDomDoc);	// Putting it in the DOM object
   
	// Releasing the resources
	SysFreeString(bstr);
	pComment->Release();

	return hr;
}

/*$ ******************************************************************************
					Method Name			CreateElement	

					Parameters			[in] LPCSTR lpcstrElementName
											Name of the element to be created

										[in] LPCSTR lpcstrElementText 
											Text of the element to be created (Can be NULL)

										[in] MSXML2::IXMLDOMNode* 
											Pareent Node, to which the new element is required to be added

										[in] bool  
												true (to immediately add the element to the parent)
												false (just create the element, but don't add now)

										[in] int 
												Indentation level
					
					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Description			Create a new element and add to the parent node (if required)
********************************************************************************** */
HRESULT CXMLMgr::CreateElement(CString lpcstrElementName, CString lpcstrElementText , MSXML::IXMLDOMNode* pParentNode , bool bAdd , int nLevel)
{
//	assert (lpcstrElementName != NULL);
	
	HRESULT hr = E_FAIL;
	MSXML::IXMLDOMElement *pElement = NULL;

	SetIndentLevel(nLevel , pParentNode);
	pElement = CreateNode(lpcstrElementName , pElement);

	if (lpcstrElementText)
		SetNodeText(lpcstrElementText , pElement);

	if (bAdd)
		hr = AppendChildToParent(pElement, pParentNode);	// Append <node> to <root>.

	if (pElement)
	{
		m_pLastItemAdded = pElement;
		hr = S_OK;
	}

	return hr;
}

/*$ ******************************************************************************
					Method Name				AddWhiteSpaceToNode

					Parameters				[in] MSXML2::IXMLDOMDocument* pDOMDoc
												Document pointer

											[in] BSTR bstrWs
												White space BSTR
								
											[in] MSXML2::IXMLDOMNode* pNode
												Node to which white space is required to be created

					Return					None

					Description				Create white spaces
********************************************************************************** */
void CXMLMgr::AddWhiteSpaceToNode(MSXML::IXMLDOMDocument* pDOMDoc, BSTR bstrWs, MSXML::IXMLDOMNode* pNode)
{
	MSXML::IXMLDOMText *pws  = NULL;
	MSXML::IXMLDOMNode *pBuf = NULL;
    
	pDOMDoc->createTextNode(bstrWs,&pws);
    pNode->appendChild(pws,&pBuf);

	if (pws)
		pws->Release();

	if (pBuf)
		pBuf->Release();
}

/*$ ******************************************************************************
					Method Name			CreateNode	

					Parameters			[in] LPCSTR
											A string specifying the name for the new element node

										[in] MSXML2::IXMLDOMElement*
											The IXMLDOMElement interface for the new element 

					Return				MSXML2::IXMLDOMElement*
											New element created

					Description			Creates an element node using the specified name
********************************************************************************** */
MSXML::IXMLDOMElement* CXMLMgr::CreateNode(CString lpcstrRootName , MSXML::IXMLDOMElement* pNode )
{
//	assert (lpcstrRootName != NULL);

	HRESULT hr = E_FAIL;
	BSTR bstr;
	wi_CStringToBSTR(lpcstrRootName , bstr);
   
	// Putting the name of the element in the DOM
	hr = m_pXMLDomDoc->createElement(bstr, &pNode);

	SysFreeString(bstr);

	return pNode;
}

/*$ ******************************************************************************
					Method Name			SetNodeText	

					Parameters			[in] LPCSTR
											Node text to set

										[in] MSXML2::IXMLDOMElement*
											Node, which text is required to be set

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Description			Set the text of the specified node
********************************************************************************** */
HRESULT CXMLMgr::SetNodeText(CString lpcstrText , MSXML::IXMLDOMElement* pNode)
{
//	assert (lpcstrText != NULL);
	assert (pNode  != NULL);

	HRESULT hr = E_FAIL;
	BSTR bstr;
	wi_CStringToBSTR(lpcstrText , bstr);

	// Writing Element To DOM
	hr = pNode->put_text(bstr);

	SysFreeString(bstr);

	return hr;
}

/*$ ******************************************************************************
					Method Name			SetIndentLevel		

					Parameters			[in] int
											Indend level
											
										[in] MSXML2::IXMLDOMNode*
											Node, which indend level is required to be set
					Return				None

					Description			---
********************************************************************************** */
void CXMLMgr::SetIndentLevel(int nLevel , MSXML::IXMLDOMNode* pParentNode)
{
	assert (nLevel >= 0);
	assert (pParentNode != NULL);

	BSTR bstr;
	CString strIndenter = _T("\n");

	for (int nCount = 0; nCount < nLevel; nCount++)
		strIndenter += _T("\t");

	wi_CStringToBSTR( strIndenter, bstr);

	AddWhiteSpaceToNode(m_pXMLDomDoc, bstr, pParentNode);

	SysFreeString(bstr);
}

/*$ ******************************************************************************
					Method Name			ReplaceElement	

					Parameters			[in] MSXML2::IXMLDOMElement* pNewElement
											New element

										[in] MSXML2::IXMLDOMElement* pOldElement
											Element to be replaced

										[in] MSXML2::IXMLDOMNode* pParent
											Parent which contains the element that is required to be replaced

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Description			Replace an existing element with the new element.
********************************************************************************** */
HRESULT CXMLMgr::ReplaceElement(MSXML::IXMLDOMElement* pNewElement , MSXML::IXMLDOMElement* pOldElement , MSXML::IXMLDOMNode* pParent)
{
	assert (pNewElement != NULL);
	assert (pOldElement != NULL);

	HRESULT hr = E_FAIL;

	MSXML::IXMLDOMNode* pElementReplaced = NULL;

	hr = pParent->replaceChild(pNewElement , pOldElement , &pElementReplaced);

	return hr;
}

/*$ ******************************************************************************
					Method Name			RemoveElement	

					Parameters			[in] MSXML2::IXMLDOMElement* pElementToRemove
											Element to be removed

										[in] MSXML2::IXMLDOMNode* pParent
											Parent that contains the element, required to be removed

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)

					Description			Remove specified element from the parent node
********************************************************************************** */
HRESULT CXMLMgr::RemoveElement(MSXML::IXMLDOMElement* pElementToRemove , MSXML::IXMLDOMNode* pParent)
{
	assert (pElementToRemove != NULL);
	assert (pParent != NULL);

	HRESULT hr = E_FAIL;

	MSXML::IXMLDOMNode * pOutNode = NULL;
	hr = pParent->removeChild(pElementToRemove , &pOutNode);

	return hr;
}

/*$ ******************************************************************************
					Method Name			RemoveElement	

					Parameters			[in] MSXML2::IXMLDOMElement*
											Element to be removed. It will determine its pareent itself

					Return				HRESULT
											S_OK (on Success)
											E_FAIL (on Error)
	
					Description			Remove a specified element
********************************************************************************** */
HRESULT CXMLMgr::RemoveElement(MSXML::IXMLDOMElement* pElementToRemove)
{
	assert (pElementToRemove != NULL);
	
	MSXML::IXMLDOMNode* pParent = GetParent(pElementToRemove);
	assert (pParent != NULL);

	HRESULT hr = E_FAIL;

	MSXML::IXMLDOMNode * pOutNode = NULL;
	hr = pParent->removeChild(pElementToRemove , &pOutNode);

	return hr;
}

/*$ ******************************************************************************
					Method Name			GetParent	

					Parameters			[in] MSXML2::IXMLDOMElement*
											Element to which parent is required

					Return				MSXML2::IXMLDOMNode*
											Parent of the element

					Description			Return the parent of the specified element
********************************************************************************** */
MSXML::IXMLDOMNode* CXMLMgr::GetParent(MSXML::IXMLDOMElement* pElement) const
{
	assert (pElement != NULL);

	MSXML::IXMLDOMNode* pNode = NULL;
	pElement->get_parentNode(&pNode);

	return pNode;
}

/*$ ******************************************************************************
					Method Name			GetChild

					Parameters			[in] const long lIndex
											Index of the child to get
								
										[in] MSXML2::IXMLDOMNodeList*
											Parent list, that contains the child

					Return				MSXML2::IXMLDOMNode*
											child pointer

					Description			Get the child element from a parent list, which index is specified.
********************************************************************************** */
MSXML::IXMLDOMNode* CXMLMgr::GetChild(const long lIndex , MSXML::IXMLDOMNodeList* pList) const
{
	assert (lIndex >= 0);
	assert (pList != NULL);

	MSXML::IXMLDOMNode* pNode;
	pList->get_item(lIndex , &pNode);

	return pNode;
}

/*$ ******************************************************************************
					Method Name			Destroy
					Parameters			None
					Return				None
					Description			Release resources
********************************************************************************** */
void CXMLMgr::Destroy()
{
	Release();
	::CoUninitialize();

}
